from collections import OrderedDict

dict_record = OrderedDict()


def collect_cost(cost):
    """
    记录耗时信息到dict_record对象中

    * 耗时如果存在就 value+=1 不存在就放入字典
    * 假设有6w数据，如果按照list收集6w个响应耗时数据再做p99 p95等指标操作
      会有内存、性能等风险
      因为实际开发中，稳定的系统，6w个响应耗时分布是比较均匀的，可能100ms占2w 150ms占2w  200ms占2w
      所以采用map的形式，极大减缓了初始数据的存储风险
      (
      map的采集形式，理论上必会小于list形式，
      什么系统能做到6w个请求均是不同响应时间？按照两位小数的形式存数据，还能做到？那它一定是牛而逼之的系统
      )
    :param cost:
    :return:
    """
    dict_record[cost] = dict_record.get(cost, 0) + 1


def calculate_percent_target(percent):
    """
    计算百分位响应指标
    :param percent: [0, 100]
    :return: res
    """
    if percent > 100:
        raise RuntimeError('指标不能大于100')
    if percent < 0:
        raise RuntimeError('指标不能小于0')
    size = len(dict_record)
    if size == 0:
        raise RuntimeError('字典记录集为空')
    # 找出位置
    # 一般都是p99 p95指标 我们前面排序按照响应耗时倒排
    # 如果95%数据在第950个，总数据是1000个，我们其实就是找倒序后的第150个
    pos = size - int(size * (percent / 100))
    record = 0
    for key_cost in reversed(dict_record):
        value = dict_record.get(key_cost)
        record += value
        if pos <= record:
            return key_cost


'''test'''
for i in range(1000):
    if i < 101 and i % 2 == 0:
        collect_cost(100)
    else:
        collect_cost(100 + i)

key = calculate_percent_target(50)
print(key)
